package com.ezgo.erc.service;

import java.io.UnsupportedEncodingException;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * 缓存业务处理类
 * 
 * @author devintam
 * 
 * @date 2015-07-02
 *
 */
@Service
public class CacheServiceImpl implements CacheService {

	public Log logger = LogFactory.getLog(this.getClass());

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	private static String redisCode = "utf-8";

	/**
	 * 删除缓存
	 * 
	 * @param keys
	 *            单个/keys数组
	 * @return long
	 */
	public long del(final String... keys) {
		return (Long) redisTemplate.execute(new RedisCallback<Object>() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				long result = 0;
				for (int i = 0; i < keys.length; i++) {
					result = connection.del(keys[i].getBytes());
				}
				return result;
			}
		});
	}

	/**
	 * 设置缓存-byte
	 * 
	 * @param key
	 *            缓存key值
	 * @param value
	 *            缓存value值
	 * @param liveTime
	 *            存活时长-单位秒
	 */
	public void set(final byte[] key, final byte[] value, final long liveTime) {
		redisTemplate.execute(new RedisCallback<Object>() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				connection.setNX(key, value);
				if (liveTime > 0) {
					connection.expire(key, liveTime);
				}
				return 1L;
			}
		});
	}

	/**
	 * 设置缓存-String
	 * 
	 * @param key
	 *            缓存key值
	 * @param value
	 *            缓存value值
	 * @param liveTime
	 *            存活时长-单位秒
	 */
	public void set(String key, String value, long liveTime) {
		this.set(key.getBytes(), value.getBytes(), liveTime);
	}

	/**
	 * 设置缓存-String
	 * 
	 * @param key
	 *            缓存key值
	 * @param value
	 *            缓存value值
	 */
	public void set(String key, String value) {
		this.set(key, value, 0L);
	}

	/**
	 * 设置缓存-byte
	 * 
	 * @param key
	 *            缓存key值
	 * @param value
	 *            缓存value值
	 */
	public void set(byte[] key, byte[] value) {
		this.set(key, value, 0L);
	}

	/**
	 * 获取缓存
	 * 
	 * @param key
	 *            缓存key值
	 * @return String
	 */
	public String get(final String key) {
		return (String) redisTemplate.execute(new RedisCallback<Object>() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				try {
					return new String(connection.get(key.getBytes()), redisCode);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
				return "";
			}
		});
	}

	/**
	 * 是否存在cache
	 * 
	 * @param key
	 *            缓存key值
	 * @return boolean
	 */
	public boolean exists(final String key) {
		return (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.exists(key.getBytes());
			}
		});
	}

	/**
	 * 删除当前操作的数据库中的key
	 * 
	 * @return String
	 */
	public String flushDB() {
		return (String) redisTemplate.execute(new RedisCallback<Object>() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				connection.flushDb();
				return "ok";
			}
		});
	}

	/**
	 * 查询数据库使用情况
	 * 
	 * @return long
	 */
	public long dbSize() {
		return (Long) redisTemplate.execute(new RedisCallback<Object>() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.dbSize();
			}
		});
	}

	/**
	 * 连接测试
	 * 
	 * @return String
	 */
	public String ping() {
		return (String) redisTemplate.execute(new RedisCallback<Object>() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.ping();
			}
		});
	}

	/**
	 * 匹配数据库中所有 key
	 * 
	 * @param pattern
	 *            正则表达式
	 * @return Set<?>
	 */
	public Set<?> Setkeys(String pattern) {
		return redisTemplate.keys(pattern);
	}

}
